from SPARQLWrapper import SPARQLWrapper, JSON;

class BlanketSubjectsGrabber(object):
    sparqlConn = SPARQLWrapper("http://dbpedia.org/sparql");
    sparqlConn.setReturnFormat(JSON);
    def __init__(self):
        print("Page Grabber initialized");
        self.__threshold = 260; # 10 times average Look at Yu, Thom, Tam "Ontology Evaluation: Using Wikipedia Categories for Browsing" 2007 pg. 6 
            
    def grabPages(self, blanket, sub, plusOneThreshold = None):
        self.__sub = sub;
        print("Grabbing pages from blanket");
        print("Threshold: "+str(self.__threshold));
        self.__subjects = set([]);
        for categoryURI in blanket:
            subjCount = 0;
            URIpacks = self.__runQuery(categoryURI);
            for URIset in URIpacks:
                self.__subjects.add(URIset["subject"]["value"][28:]);
                subjCount += 1;
            if(subjCount <= self.__threshold and categoryURI in sub):
                print(categoryURI +": "+ str(subjCount)); 
                self.__grabPlusOne(categoryURI, plusOneThreshold);
            else:
                print("There is enough info here:" + str(subjCount));
        return self.__subjects;
    
    def __grabPlusOne(self, categoryURI, plusOneIterations = None):
        if plusOneIterations == None: plusOneIterations = 2;
        print("In PlusOne function with "+categoryURI+" and "+ str(plusOneIterations)+" to go");
        plusOneURI = None;
        resultSet = self.__runPlusOneQuery(categoryURI);
        for result in resultSet: 
            print(categoryURI);
            print(result["o"]["value"]);
            if(result["o"]["value"] != categoryURI): 
                print(result["o"]["value"]+"is not equal to"+categoryURI+"\n");
                break;
            else: #We will be grabbing a subclass...
                print("They are equal, so we are grabbing subclass")
                print(result["s"]["value"]);
                if(len(result["s"]["value"]) <= 36): continue;
                else:
                    if(result["s"]["value"][36] != ":"): continue;
                    else: #Then its a category
                        if(result["s"]["value"] == categoryURI or result["s"]["value"] in self.__sub): continue;
                        else:
                            print("all good!");
                            plusOneURI = result["s"]["value"];
                            if(len(plusOneURI) < 36): continue;
                            else:
                                if(plusOneURI[36] != ":"): continue;
                                else:
                                    #Then we need to grab the subjects corresponding to these...
                                    if(plusOneURI != None):
                                        subjCount = 0;
                                        URIpacks = self.__runQuery(plusOneURI);
                                        for URIset in URIpacks:
                                            print(URIset["subject"]["value"]);
                                            self.__subjects.add(URIset["subject"]["value"][28:]);
                                            subjCount += 1;
                                        if (subjCount <= self.__threshold and plusOneIterations != 0):
                                            self.__grabPlusOne(plusOneURI, plusOneIterations - 1);
                     
        print("done with "+ categoryURI);
                    
                
        
    def __runPlusOneQuery(self, categoryURI):  
        query = self.__buildPlusOneQuery(categoryURI);
        BlanketSubjectsGrabber.sparqlConn.setQuery(query);
        BlanketSubjectsGrabber.sparqlConn.setReturnFormat(JSON);
        resultSet = BlanketSubjectsGrabber.sparqlConn.query().convert();
        return resultSet["results"]["bindings"];   
        
    def __runQuery(self, categoryURI):
        query = self.__buildQuery(categoryURI);
        BlanketSubjectsGrabber.sparqlConn.setQuery(query);
        BlanketSubjectsGrabber.sparqlConn.setReturnFormat(JSON);
        resultSet = BlanketSubjectsGrabber.sparqlConn.query().convert();
        return resultSet["results"]["bindings"];
    
    def __buildQuery(self, categoryURI):
        query= ("PREFIX skos: <http://www.w3.org/2004/02/skos/core#> "
                "SELECT ?subject "
                "WHERE { ?subject skos:subject <" + categoryURI + "> }"); 
        return query;
    
    def __buildPlusOneQuery(self, categoryURI):
        query = ("DESCRIBE <"+categoryURI+">");
        return query;
    
    
        
        